#include "input.h"

Loader::Loader(string file, Map* map, Keyboard* k)
{
  string ignore;
  string nextLine;
  char nextc;
  int x, y, hash, ID;
  ifstream in (file.c_str());
  MTEntry* entry;

  MTable = new MonsterTable();

  in >> map->height;
  getline(in, ignore);
  in >> map->width;

  map->map = new Space**[map->height];

  for (int i = 0; i < map->height; i++)
  {
    map->map[i] = new Space*[map->width];
    getline(in, ignore);
    for (int j = 0; j < map->width; j++)  
    {
      in >> nextc;
      switch (nextc)
      {
        case '#' :
	  map->map[i][j] = new Space(true, false);
	  break;
        case '.' :
	  map->map[i][j] = new Space(false, false);
	  break;
	case '+' :
	  map->map[i][j] = new Space(false, true);
	  break;
	case '\'' :
	  map->map[i][j] = new Space(false, true);
	  map->map[i][j]->openDoor();
	  break;
      }
    }
  }

  Player* p = new Player(map,k);
  while (!in.eof())
  {
    in >> x;
    in >> y;
    in >> hash;
    map->map[x][y]->load(hash);
    getline(in, ignore);
    getline(in, nextLine);
    while (nextLine != "==========")
    {
      if (nextLine == "PLAYER")
      {
        map->map[x][y]->addPlayer(p);
	map->posX = x;
	map->posY = y;

	in >> ID;
	map->creatures.push_back(p);
	// The ID is thrown away atm, should error out if it's not 0
	getline(in, ignore);
      }
      if ((entry = MTable->lookup_name(nextLine)) != NULL)
      {
	Monster* m = new Monster(map, entry, x, y);
	map->map[x][y]->addMonster(m);	

	in >> ID;
	m->setID(ID);
	//map->creatures.push_back(m);
	getline(in, ignore);
      }
      getline(in, nextLine);
    }
    getline(in, ignore);
  }

  //map->creatures.push_back(p);

  in.close();
}

Keyboard::Keyboard(Map* m, Screen* s)
{
  message = "No message";
  status = 0;
  map = m;
  screen = s;
  count = 0;
}

int Keyboard::makeMove()
{
  stringstream s;

  int c = getch();

  switch(c) 
  {
    case 'Q' : 
      status = -1;
      message = "Exiting program!";
      break;
    case '1' :
      direction(1,-1);
      break;
    case '2' :
      direction(1,0);
      break;
    case '3' :
      direction(1,1);
      break;
    case '4' :
      direction(0,-1);
      break;
    case '6' :
      direction(0,1);
      break;
    case '7' :
      direction(-1,-1);
      break;
    case '8' :
      direction(-1,0);
      break;
    case '9' :
      direction(-1,1);
      break;
    case 'c' :
      close();
      break;
    default:
      status = 0;
      s << "No message, press " << count++ << ".  Button pressed: " << c;
      message = s.str();  
      break;
  }
  screen->addMessage(message.c_str());
  screen->mesPrint();
  screen->mapPrint();

  return status;
}

void Keyboard::direction(int x, int y)
{
  int s = map->movePos(x,y);
  stringstream st;
  if (s == 0)
  {
    status = 0;
    if (x == 1)
      st << "S";
    if (x == -1)
      st << "N";
    if (y == 1)
      st << "W";
    if (y == -1)
      st << "E";
    st << " move completed.  Current position: " << map->getPosX() << ", " << map->getPosY();
    message = st.str();
    return;
  }
  if (s == 1)
  {
    status = 0;
    st << "Ran into wall.  Current position: " << map->getPosX() << ", " << map->getPosY();
    message = st.str();
    return;
  }
  if (s == 2)
  {
    status = 0;
    st << "ERROR: Tried to walk outside of map's bounds.  Current position: " << map->getPosX() << ", " << map->getPosY();
    message = st.str();
    return;
  }
  if (s == 3)
  {
    status = 0;
    st << "Door opened";
    message = st.str();
    return;
  }
  if (s == 4)
  {
    status = 0;
    st << "That's a monster!";
    message = st.str();
    return;
  }
}

void Keyboard::close()
{
  int x, y, dispX, dispY;
  screen->addMessage("Please enter direction.");
  screen->mesPrint();
  char c = getch();
  switch (c)
  {
    case '1':
      dispX = 1;
      dispY = -1;
      break;
    case '2':
      dispX = 1;
      dispY = 0;
      break;
    case '3':
      dispX = 1;
      dispY = 1;
      break;
    case '4':
      dispX = 0;
      dispY = -1;
      break;
    case '6':
      dispX = 0;
      dispY = 1;
      break;
    case '7':
      dispX = -1;
      dispY = -1;
      break;
    case '8':
      dispX = -1;
      dispY = 0;
      break;
    case '9':
      dispX = -1;
      dispY = 1;
      break;
    default:
      screen->addMessage("Invalid direction.");
      return;
  }
  x = map->getPosX();
  y = map->getPosY();
  if (map->getSpace(x + dispX, y + dispY)->isOpen())
  {
    map->getSpace(x + dispX, y + dispY)->closeDoor();
    status = 0;
    message = "Closed Door.";
    return;
  }
  if (map->getSpace(x + dispX, y + dispY)->isClosed())
  {
    status = 0;
    message = "Door already closed.";
    return;
  }
  else
  {
    status = 0;
    message = "No door there.";
    return;
  }
}

string Keyboard::getMessage()
{
  return message;
}

int Keyboard::getStatus()
{
  return status;
}
